package com.seleniti.enpareja.web.desktop.client.control.entrypoint;

import org.ioc.commons.flowcontrol.common.impl.ReceiverAdapter;
import org.ioc.commons.flowcontrol.eventbus.EventHandler;
import org.ioc.commons.flowcontrol.exceptionparser.ExceptionParserManager.ExceptionParser;
import org.ioc.commons.impl.gwt.client.ui.Css3Util;
import org.ioc.commons.impl.gwt.client.ui.Css3Util.Css3EffectQueue.DisappearEffectType;
import org.ioc.commons.impl.gwt.client.ui.Css3Util.Css3Toolkit;
import org.ioc.commons.impl.gwt.client.ui.Css3Util.VisibilityModeStyle;
import org.ioc.commons.impl.gwt.client.ui.HasOneWidgetWrapper;
import org.ioc.commons.utils.FormatterLogger;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.RootPanel;
import com.seleniti.enpareja.controller.common.exception.EnParejaException;
import com.seleniti.enpareja.controller.control.factory.ClientFactory;
import com.seleniti.enpareja.controller.control.factory.EnParejaAppController;
import com.seleniti.enpareja.controller.control.factory.EnParejaAppController.Parameters;
import com.seleniti.enpareja.controller.ui.base.EnParejaBasePresenter;
import com.seleniti.enpareja.web.appbase.client.control.controller.EnParejaExceptionControllerImpl;
import com.seleniti.enpareja.web.desktop.client.ui.resources.CommonResources;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class EnParejaDesktop implements EntryPoint, ExceptionParser<EnParejaException> {
	private static final FormatterLogger logger = FormatterLogger
			.getLogger(EnParejaDesktop.class);

	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {
		/**
		 * We delegate the exception control to class ExceptionController. It
		 * needs to be the first step in order to capture whichever later
		 * exception.
		 */
		GWT.setUncaughtExceptionHandler(EnParejaExceptionControllerImpl.get()
				.getHandler());

		logger.info("Initializing '{0}' module on GWT version: {1}",
				GWT.getModuleName(), GWT.getVersion());

		/**
		 * Injecting common css style into the browser
		 */
		CommonResources.INSTANCE.style().ensureInjected();

		/**
		 * Instance of client factory
		 */
		ClientFactory clientFactory = GWT.create(ClientFactory.class);

		/**
		 * Setting client factory
		 */
		EnParejaBasePresenter.setClientFactory(clientFactory);
		EnParejaExceptionControllerImpl.get().setClientFactory(clientFactory);
		
		/**
		 * Setting global exception controller
		 */
		ReceiverAdapter.setGlobalExceptionController(clientFactory.getExceptionController());

		/**
		 * Main container (body)
		 */
		RootPanel mainContainer = RootPanel.get("mainContainer");

		/**
		 * The App
		 */
		EnParejaAppController theApp = clientFactory.getAppController().forThisObject(this);

		/**
		 * Registering exception parser
		 */
		clientFactory.getExceptionController().registerExceptionParser(EnParejaException.class,
				this);

		/**
		 * When application is ready...
		 */
		theApp.eventBus().bindEvent(EnParejaAppController.Event.ApplicationReady,
				new EventHandler<EnParejaAppController.Event>() {

					@Override
					public void handleEvent(Object sender,
							EnParejaAppController.Event event, Object... params) {
						/**
						 * ... the loading symbol will disappear
						 */
						Element loadingLogo = DOM.getElementById("logoContainer");

						Css3Toolkit toolkit = Css3Util.getToolkit(loadingLogo);
						toolkit.disappear(DisappearEffectType.MOVE_TO_LEFT, VisibilityModeStyle.USE_DISPLAY_PROPERTY, 1000);

						logger.info("... app running OK.");
					}
				});

		Parameters appParameters = new Parameters();

		String forceLog = Window.Location.getParameter("forceLog");
		appParameters.forceLog = Boolean.parseBoolean(forceLog);

		/**
		 * Running the application
		 */
		logger.info("Running the app...");
		theApp.run(HasOneWidgetWrapper.from(mainContainer), appParameters);

		logger.info("'{0}' module initialized OK", GWT.getModuleName());
	}

	@Override
	public EnParejaException fromMessage(String message) {
		return EnParejaException.fromMessage(message);
	}

	@Override
	public boolean tryHandleException(Throwable e) {
		return false;
	}
}
